package au.edu.unsw.editingtool.global;

/* This class is used to grab a metadata from resitory and transformation of the metadata to valetxml
 * The steps to do are:
 * 1. Set xml file which will be written to when the class grabs a metadata from repository.
 * 2. Set output file which is the result file for transformation.
 * 3. Set the XSL file location for transformation.
 * $. Then we can used the command to grab and transform
 */

import java.io.*;
import java.util.*;
import java.util.regex.*; 

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import au.edu.unsw.editingtool.fedora.FedoraFactory;
import au.edu.unsw.editingtool.transformxml.XMLProcessor;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern;


public class Metadata {
	// XML Location
	private String xmlfile;
	
	//XSL Location
	private String xslfile;
	
	//Temporary output file 
	private String outputfile;
	
	public Metadata()
	{
		super();
	}
	
	public void setXMLFile(String template, String extension)
	{
		File tempfile = null;
		try {
			tempfile = File.createTempFile(template, extension);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.xmlfile = tempfile.getAbsolutePath();	
	}
	
	public String getXMLFile()
	{
		return this.xmlfile;
	}

	public void setXSLFile(String file)
	{
		this.xslfile = file;
	}
	
	public String getXSLFile()
	{
		return this.xslfile;
	}
	
	public void setOuputFile(String template, String extension)
	{		
		File tempfile = null;
		try {
			tempfile = File.createTempFile(template, extension);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.outputfile = tempfile.getAbsolutePath();
	}
	
	public String getOuputFile()
	{
		return this.outputfile;
	}
	
	public boolean getMetadata(String url, String username, String password, String id, String metadata)
	{
		FedoraFactory fedora = new FedoraFactory(url, username, password);		
		//Setup fedora and get the VALET XML													
		byte[] xml;
		try {
			xml = fedora.getDatastream(id, metadata);
			FileOutputStream fos = new FileOutputStream(this.xmlfile);
			fos.write(xml);
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}
	
	public void transform()
	{			
		XMLProcessor processor = new XMLProcessor();
		try {			
			File xml = new File(this.xmlfile);			
			processor.setOutFile(this.outputfile);			
			processor.setXml(xml.getAbsolutePath());			
										
			System.out.println("XSL : "+this.xslfile);					
			processor.setXsl(this.xslfile);
			processor.xmlProcessor("");												
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	public Hashtable<String,String> transformOuputFileToHash()
	{
		String path = "//Formdata";
		DocumentBuilderFactory dom = DocumentBuilderFactory.newInstance();
		Hashtable<String, String> results = new Hashtable<String, String>();
		dom.setNamespaceAware(true);
		DocumentBuilder builder = null;
		Document doc = null;
		XPathExpression expr = null;
		NodeList nodes = null;
		NodeList resultnodes = null;
		try {
			builder = dom.newDocumentBuilder();
			doc = builder.parse(new File(this.outputfile));
			doc.getDocumentElement().normalize();	        					
			XPathFactory factory = XPathFactory.newInstance();
			XPath xpath = factory.newXPath();
			expr = xpath.compile(path);
			nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
			resultnodes = nodes.item(0).getChildNodes();	
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		for (int i = 0; i < resultnodes.getLength(); i++)
		{
			Node nd = resultnodes.item(i);
			//System.out.println("[METADATA] transformOuputFileToHash : "+nd.getNodeName()+":"+nd.getTextContent());
			results.put(nd.getNodeName(), nd.getTextContent());
		}	
		return results;
	}
	
	public String transformHashToJavaScriptAssociativeArray()
	{	
		return transformHashToJavaScriptAssociativeArray(transformOuputFileToHash());
	}
	
	public static String transformHashToJavaScriptAssociativeArray(Hashtable <String,String> table)
	{
		String js_array = "response = { ";
		
		Hashtable<String,String> ht = table;
		
		Enumeration<String> keys = ht.keys();
		while(keys.hasMoreElements())
		{
			String key = keys.nextElement();
			js_array += "'"+key+"' : '"+javascript_escape(ht.get(key))+"',";
		}
		
		String patternString = ",$";
		java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(patternString);
		Matcher matcher = pattern.matcher(js_array);
		js_array = matcher.replaceAll("");		
		js_array += " };";
		
		return js_array;
	}	
	
	public static String javascript_escape(String data)
	{		
		String result = null;
		
		String patternStr = "\\n";
		String replacementStr = "\\n";		
		java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(patternStr);
		Matcher matcher = pattern.matcher(data);
		result = matcher.replaceAll(replacementStr);
		
		patternStr = "\\r";
		replacementStr = "\\r";
		pattern = java.util.regex.Pattern.compile(patternStr);
		matcher = pattern.matcher(result);
		result = matcher.replaceAll(replacementStr);
		
		patternStr = "\\'";
		replacementStr = "\\\'";
		pattern = java.util.regex.Pattern.compile(patternStr);
		matcher = pattern.matcher(result);
		result = matcher.replaceAll(replacementStr);
				
		return result;			
	}

}
